package extractor;

import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LinkExtractor {
	private boolean wikipedia;

	private static final String HTML_TAG_PATTERN = "(?i)<a([^>]+)>(.+?)</a>";
	private static final String HTML_HREF_TAG_PATTERN = "\\s*(?i)href\\s*=\\s*(\"([^\"]*\")|'[^']*'|([^'\">\\s]+))";
	private static final String HTML_SPAN_PATTERN = "<span([^>]+)>(.+?)</span>";

	private static final String sCitation = "<span>[</span>";

	public LinkExtractor() {

	}

	public Vector<HtmlLink> grabLinks(String html) {
		if (html == null)
			return null;

		Vector<HtmlLink> result = new Vector<HtmlLink>();

		Pattern patternTag = Pattern.compile(HTML_TAG_PATTERN);
		Pattern patternLink = Pattern.compile(HTML_HREF_TAG_PATTERN);
		Pattern patternSpan = Pattern.compile(HTML_SPAN_PATTERN);
		Matcher matcherTag = patternTag.matcher(html);

		while (matcherTag.find()) {

			String href = matcherTag.group(1); // href
			String anchor = matcherTag.group(2); // link text

			Matcher matcherLink = patternLink.matcher(href);

			while (matcherLink.find()) {

				String link = matcherLink.group(1); // link
				if (link.startsWith("\""))
					link = link.substring(1, link.length() - 1);
				HtmlLink r = new HtmlLink(link, anchor);

				if (wikipedia) {
					if (link.startsWith("/w/"))
						continue;

					// wikipedia: citations are either superscript, ^, or [#]
					// <sup><i><b>a</b></i></sup>
					// <span>[</span>66<span>]</span>
					int idx = anchor.indexOf(sCitation);
					if (idx != -1) {
						r.citation = true;
						r.anchor = "citation ["
								+ anchor.substring(sCitation.length(), anchor.indexOf("<span>]</span>")) + "]";
					} else if (anchor.equals("^")) {
						r.citation = true;
						r.anchor = "citation [?]";
					} else if (anchor.startsWith("[") && anchor.endsWith("]")) {
						r.citation = true;
						r.anchor = "citation " + anchor;
					} else if (anchor.indexOf("<span") != -1) {
						// catch formatted anchor text
						Matcher matcherSpan = patternSpan.matcher(anchor);
						StringBuilder sb = new StringBuilder();
						while (matcherSpan.find()) {
							sb.append(matcherSpan.group(2));
							sb.append(" ");
						}
						r.anchor = sb.toString().trim();
					}
				}

				// if (r.citation)
				// System.out.println("---> CITATION: anchor = " + r.anchor +
				// ", link = " + r.link);
				// else
				// System.out.println("---> LINK: anchor = " + r.anchor +
				// ", link = " + r.link);

				result.add(r);
			}
		}

		return result;

	}

	public static class HtmlLink {
		public boolean citation = false;
		public String link;
		public String anchor;

		HtmlLink(String link, String anchor) {
			this.link = link.trim().toLowerCase();
			this.anchor = anchor.trim().toLowerCase();
		}
	}

	public boolean isWikipedia() {
		return wikipedia;
	}

	public void setWikipedia(boolean wikipedia) {
		this.wikipedia = wikipedia;
	}
}